<template>
  <a-modal
    v-bind="$attrs"
    :wrap-class-name="fullModalClass"
    :wrap-style="{ overflow: 'auto' }"
    :width="modalWidth"
    :footer="footer"
    :body-style="customBodyStyle"
    :keyboard="keyboard"
    :mask-closable="maskClosable"
    :open="visible"
    :get-container="getCustomContainer"
    :mask-style="customMaskStyle"
  >
    <template v-if="showTitle" #title>
      <div class="header-bar">
        <span ref="modalTitleRef" class="headerBarLeft">
          <template v-if="slots.title">
            <slot name="title" />
          </template>
          <template v-else>
            {{ title }}
          </template>
        </span>
        <span v-if="adjustSize" class="modal_full" @click="fullDialog">
          <avic-icon :svg="sizeState ? 'FullscreenExitOutlined' : 'FullscreenOutlined'" />
        </span>
      </div>
    </template>
    <template v-if="slots.footer" #footer>
      <slot name="footer" />
    </template>
    <template #modalRender="{ originVNode }">
      <div ref="modalRef" :style="transformStyle">
        <component :is="originVNode" />
        <!--主要增加这个元素用于拖拽的时候显示能够变化的大小-->
        <div class="modal-drag-position" />
      </div>
    </template>
    <slot />
  </a-modal>
</template>

<script setup lang="ts">
import type { ComputedRef, CSSProperties } from 'vue';
import { useRoute } from 'vue-router';
import { useModalDrag, useModalMove } from './useModalHooks';
import { useWindowSize } from '@vueuse/core';
const { proxy } = getCurrentInstance();
const windowSize = useWindowSize();
const slots = useSlots();
const props = defineProps({
  /** 弹框标题 */
  title: { type: String, default: '' },
  /** 是否显示标题区域 */
  showTitle: { type: Boolean, default: true },
  /** 弹框宽度，支持具体宽度和百分比 */
  width: { type: String, default: '' },
  /** 弹框高度，支持具体高度和百分比 */
  height: { type: String, default: '' },
  /** 是否展示全屏按钮 */
  adjustSize: { type: Boolean, default: true },
  /** 初始化是否全屏 */
  fullScreen: { type: Boolean, default: false },
  /** 是否支持弹框拖拽大小 */
  draggable: { type: Boolean, default: true },
  /** Modal组件原生属性Modal body 样式 */
  bodyStyle: { type: Object, default: undefined },
  /** Modal组件原生属性--底部内容,当不需要默认底部按钮时，可以设为:footer="null" */
  footer: { type: Object, default: undefined },
  /** Modal组件原生属性--对话框外层容器的类名 */
  wrapClassName: { type: String, default: '' },
  /** 是否支持键盘 esc 关闭 */
  keyboard: { type: Boolean, default: false },
  /** 点击蒙层是否允许关闭 */
  maskClosable: { type: Boolean, default: false },
  /** 兼容antd v3.x */
  visible: { type: Boolean, default: false },
  /** Modal组件原生属性Mask  样式 */
  maskStyle: { type: Object, default: undefined },
  /** Modal组件原生属性, getContainer 优先级高于 placement */
  getContainer: { type: Function, default: null },
  /** Modal组件挂载位置, 设置为body时，弹窗挂载在body元素下，设置为tab时，弹窗挂载在标签页页面下 */
  placement: { type: String, default: 'body' }
});
const modalHeight = ref(props.height);
const customPlacement = props.placement || proxy.$settings.modal.placement;
/** 支持弹框高度百分比 */
function computedModalHeight() {
  let heightInt = 0;
  if (modalHeight.value && modalHeight.value && modalHeight.value.indexOf('%') >= 0) {
    const windowHeight = windowSize.height.value;
    const heightBfb = modalHeight.value.replace('%', '');
    const computedHeight = (windowHeight / 100) * parseInt(heightBfb);
    heightInt = parseInt(computedHeight.toString());
  } else {
    const heightStr = modalHeight.value.replace('px', '');
    heightInt = parseInt(heightStr.toString());
  }
  if (props.showTitle || slots.title) {
    heightInt = heightInt - 46.8;
  }
  if (!props.footer || slots.footer) {
    heightInt = heightInt - 56.8;
  }
  modalHeight.value = `${heightInt}px`;
}

const sizeState = ref(null);
const customBodyStyle = ref();
const fullModalClass = ref();
const modalWidth = ref(props.width);
let isChangeSize = false;
nextTick(() => {
  sizeState.value = props.fullScreen;
  if (!props.fullScreen) {
    computedModalHeight();
  }
  changeSizeStateFn();
});
/** modal 全屏状态设置 */
function changeSizeStateFn() {
  if (sizeState.value) {
    fullModalClass.value = `full-modal ${props.wrapClassName}`;
    customBodyStyle.value = props.bodyStyle;
    modalWidth.value = '100%';
  } else {
    const modalAbsolute = customPlacement == 'tab' ? 'modal-absolute' : '';
    fullModalClass.value = `modalFixed ${props.wrapClassName} ${modalAbsolute}`;
    if (isChangeSize) {
      // customBodyStyle.value = { height: initHeight, overflowY: 'auto' };
      customBodyStyle.value = Object.assign({ height: initHeight, overflowY: 'auto' }, props.bodyStyle);
      modalWidth.value = initWidth;
    } else {
      // customBodyStyle.value = { height: modalHeight.value, overflowY: 'auto' };
      customBodyStyle.value = Object.assign({ height: modalHeight.value, overflowY: 'auto' }, props.bodyStyle);
      modalWidth.value = props.width;
    }
  }
}
let initWidth = '0px';
let initHeight = '0px';
const modalRef = ref(null);
function changePosition() {
  isChangeSize = true;
  initWidth = `${modalRef.value.clientWidth}px`;
  // 根据后续逻辑，推测此处减107为计算modal中body的高度
  // 补全适配无footer场景的逻辑
  // initHeight = `${modalRef.value.clientHeight - 107}px`;
  const headerHeihgt = modalRef.value?.querySelector('.ant-modal-header')?.clientHeight || 0;
  const footerHeight = modalRef.value?.querySelector('.ant-modal-footer')?.clientHeight || 0;
  initHeight = `${modalRef.value.clientHeight - (headerHeihgt + footerHeight)}px`;
  modalHeight.value = initHeight;
  changeSizeStateFn();
}
/** modal拖拽大小实现 */
nextTick(() => {
  if (props.draggable) {
    useModalDrag(modalRef, sizeState, changePosition);
  }
});

/** 浏览器size发生变化的时候也调用这个函数 */
window.addEventListener('resize', () => {
  nextTick(() => {
    if (props.draggable) {
      useModalDrag(modalRef, sizeState, changePosition);
    }
  });
});
let oldTransformStyle = {} as ComputedRef<CSSProperties>;
/** modal全屏实现 */
function fullDialog() {
  if (!sizeState.value) {
    oldTransformStyle = transformStyle;
  }
  sizeState.value = !sizeState.value;
  changeSizeStateFn();
  if (!sizeState.value && oldTransformStyle.value) {
    transformStyle = oldTransformStyle;
  }
}
/** modal移动实现 */
const modalTitleRef = ref<HTMLElement>(null);
let { transformStyle } = useModalMove(modalTitleRef, sizeState);

const route = useRoute();
const customMaskStyle = ref();
onBeforeMount(() => {
  // 挂载位置设置为tab时，挂载在对应的标签页下
  customMaskStyle.value = props.maskStyle;
  if (customPlacement == 'tab') {
    generateContainer();
    // 遮罩需要修改为absolute
    customMaskStyle.value = Object.assign({ position: 'absolute' }, props.maskStyle);
  }
});
function generateContainer() {
  if (route) {
    const existContainer = document.getElementById(route.path);
    if (!existContainer) {
      // 动态插入元素，挂载在插入的元素中
      const parentElement = document.getElementById('main_content');
      if (parentElement) {
        const container = parentElement.firstElementChild.firstElementChild;
        const newDiv = document.createElement('div');
        newDiv.style.position = 'static';
        newDiv.style.top = '0';
        newDiv.style.left = '0';
        newDiv.style.right = '0';
        newDiv.style.bottom = '0';
        newDiv.setAttribute('id', route.path);
        container.appendChild(newDiv);
      }
    }
  }
}
function getCustomContainer() {
  if (route) {
    const container = document.getElementById(route.path);
    return props.getContainer || container || document.body;
  }
  return props.getContainer || document.body;
}
</script>
<style lang="less" scoped>
:deep(.header-bar) {
  display: inline-flex;
  flex: 0;
  align-items: center;
  width: 100%;
  padding: 0;
  border-radius: 4px;
  transition: all 0.3s;
}

:deep(.headerBarLeft) {
  flex: 1;
  margin: 0;
  text-align: left;
  cursor: move;
}
:deep(.modal_full) {
  width: 30px;
  margin-right: 32px;
  margin-left: auto;
  text-align: right;
  cursor: pointer;
  color: @text-color-secondary;
}
</style>
